/*
* Copyright (C) 2015 Brent Marriott
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package com.hookedonplay.decoviewlib.charts;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Matrix;
import android.graphics.RectF;
import android.graphics.SweepGradient;
import android.support.annotation.NonNull;
abstract public class ArcSeries extends ChartSeries {
/**
* Angle that the arc starts
*/
protected float mArcAngleStart;
/**
* Sweep angle starts at {@link #mArcAngleStart}
*/
protected float mArcAngleSweep;
ArcSeries(@NonNull SeriesItem seriesItem, int totalAngle, int rotateAngle) {
super(seriesItem, totalAngle, rotateAngle);
}
/**
* Draw the arc in the current state
*
* @param canvas Canvas to draw onto
*/
abstract void drawArc(Canvas canvas);
/**
* Draw this arc in the current position calculated by the ValueAnimator.
*
* @param canvas Canvas used to draw
* @param bounds Bounds to be used to draw the arc
* @return true is draw view has been handled
*/
@Override
public boolean draw(Canvas canvas, RectF bounds) {
if (super.draw(canvas, bounds)) {
return true;
}
final float endPos = calcCurrentPosition(mPositionStart, mPositionEnd, mSeriesItem.getMinValue(), mSeriesItem.getMaxValue(), mPercentComplete);
mArcAngleSweep = adjustSweepDirection(verifyMinSweepAngle(endPos * mAngleSweep));
mArcAngleStart = mAngleStart;
if (mSeriesItem.getDrawAsPoint()) {
mArcAngleStart = adjustDrawPointAngle(mArcAngleSweep);
mArcAngleSweep = adjustSweepDirection(getMinSweepAngle());
} else if (mArcAngleSweep == 0) {
return true;
}
return false;
}
/**
* Build a gradient if required. This must be executed every time the bounds changes
*/
protected void applyGradientToPaint() {
if (Color.alpha(mSeriesItem.getSecondaryColor()) != 0) {
SweepGradient gradient;
if (mAngleSweep < 360) {
/**
* When we have less than a full circle we change the style of gradient so that
* the two colors start at the same point. The two provided colors meet rather than
* a fade the complete circumference. A matrix is rotated so the meeting of the
* two colors occurs in the middle of the gap when the part circle is not drawn
*/
final int[] colors = {mSeriesItem.getColor(), mSeriesItem.getSecondaryColor()};
final float[] positions = {0, 1};
gradient = new SweepGradient(mBounds.centerX(), mBounds.centerY(), colors, positions);
Matrix gradientRotationMatrix = new Matrix();
gradientRotationMatrix.preRotate(mAngleStart - ((360f - mAngleSweep) / 2), mBounds.centerX(), mBounds.centerY());
gradient.setLocalMatrix(gradientRotationMatrix);
} else {
/**
* Drawing a gradient around the complete circumference of the circle. This
* gradient fades gently between the two colors.
*/
final int[] colors = {mSeriesItem.getSecondaryColor(), mSeriesItem.getColor(), mSeriesItem.getSecondaryColor()};
final float[] positions = {0, 0.5f * (mAngleSweep / 360f), 1};
gradient = new SweepGradient(mBounds.centerX(), mBounds.centerY(), colors, positions);
}
mPaint.setShader(gradient);
}
}
}